﻿using HalconDotNet;
using IniReadWrite;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisionRoc.Tool;

namespace VisionRoc.Core
{
    public class SetArc
    {
        public string ArcPath;
        public SetArc(string _Path)
        {
            HOperatorSet.GenEmptyObj(out Spoke);
            HOperatorSet.GenEmptyObj(out Arc);
            HOperatorSet.GenEmptyObj(out Cross);
            //判断文件路径是否存在
            if (!Directory.Exists(_Path))
            {
                Directory.CreateDirectory(_Path);
            }
            ArcPath = _Path + "\\Arc.ini";
            if (File.Exists(ArcPath))
            {
                ReadParameter();
            }
        }

        /// <summary>
        /// 绘制Arc输出Row坐标
        /// </summary>
        public double[] Rows = new double[5];

        /// <summary>
        /// 绘Arc输出Col坐标
        /// </summary>
        public double[] Cols = new double[5];

        #region 显示参数

        /// <summary>
        /// 显示点位置
        /// </summary>
        public bool DisplayLoction;

        /// <summary>
        /// 显示线段
        /// </summary>
        public bool DisplayArc;

        /// <summary>
        /// 显示卡尺
        /// </summary>
        public bool DisplayCalib;

        /// <summary>
        /// 线宽
        /// </summary>
        public int LineWidth;

        /// <summary>
        /// 位置大小
        /// </summary>
        public int CrossSize;

        /// <summary>
        /// 位置颜色
        /// </summary>
        public string CrossColor;

        /// <summary>
        /// 卡尺颜色
        /// </summary>
        public string CalibColor;

        /// <summary>
        /// 线段颜色
        /// </summary>
        public string ArcColor;
        #endregion

        #region 参数
        [Browsable(true), Description("卡尺数量：该值的一般区间: 1 ≤ Elements ≤ 100000"), Category("工具参数"), ReadOnly(false)]
        public int Elements { get; set; }

        [Browsable(true), Description("卡尺高度：\r\n建议值: 30, 60, 90, 120"), Category("工具参数"), ReadOnly(false)]
        public int DetectHeight { get; set; }

        [Browsable(true), Description("卡尺宽度：\r\n建议值: 5, 10, 15, 20, 25, 30"), Category("工具参数"), ReadOnly(false)]
        public int DetectWidth { get; set; }

        [Browsable(true), Description("滤波因子：高斯滤波因子\r\n建议值: 0.5, 1, 1.5, 2, 2.5, 3"), Category("工具参数"), ReadOnly(false)]
        public double Sigma { get; set; }

        [Browsable(true), Description("边缘幅度：边缘幅度阈值\r\n建议值: 5, 10, 15, 20, 25, 30, 40"), Category("工具参数"), ReadOnly(false)]
        public int Threshold { get; set; }

        [Browsable(true), Description("边缘极性：positive表示由黑到白,\r\nnegative表示由白到黑,\r\nall表示以上两种方向"), TypeConverter(typeof(GenderItem1)), Category("工具参数"), ReadOnly(false)]
        public string Transition { get; set; }

        [Browsable(true), Description("点选择：first表示选择第一点,\r\nlast表示选择最后一点,\r\nmax表示选择边缘幅度最强点"), TypeConverter(typeof(GenderItem_Two)), Category("工具参数"), ReadOnly(false)]
        public string Select { get; set; }
        #endregion

        /// <summary>
        /// 拟合输出卡尺区域
        /// </summary>
        HObject Spoke;

        /// <summary>
        /// 圆弧
        /// </summary>
        HObject Arc;

        /// <summary>
        /// 位置十字叉
        /// </summary>
        HObject Cross;

        /// <summary>
        /// spoke 输出参数
        /// </summary>
        public HTuple ResultRow = new HTuple();

        /// <summary>
        /// spoke 输出参数
        /// </summary>
        public HTuple ResultCol = new HTuple();

        /// <summary>
        /// 圆中心Row
        /// </summary>
        public HTuple RowCenter = new HTuple();

        /// <summary>
        /// 圆中心Col
        /// </summary>
        public HTuple ColCenter = new HTuple();

        /// <summary>
        /// 圆半径
        /// </summary>
        public HTuple RadiusCircle = new HTuple();

        /// <summary>
        /// 圆起始弧度
        /// </summary>
        public HTuple StartPhi = new HTuple();

        /// <summary>
        /// 圆终点弧度
        /// </summary>
        public HTuple EndPhi = new HTuple();

        /// <summary>
        /// 圆弧角度
        /// </summary>
        public HTuple ArcAngle = new HTuple();

        /// <summary>
        /// 圆弧拟合成功状态
        /// </summary>
        public bool FitCircleState = false;

        /// <summary>
        /// 拟合圆弧
        /// </summary>
        public void Fit_Arc(HObject Image, HWindow hWindow, HTuple Rows1, HTuple Cols1)
        {
            Spoke.Dispose();
            MyHOperatorSet.spoke(Image, out Spoke, Elements, DetectHeight, DetectWidth, Sigma, Threshold, Transition, Select, Rows1, Cols1, "outer", out ResultRow, out ResultCol, out _);
            if (ResultRow.TupleLength() > 0 && ResultRow.D > 0)
            {
                Arc.Dispose(); RowCenter.Dispose();
                MyHOperatorSet.pts_to_best_circle(out Arc, ResultRow, ResultCol, 3, "arc", out RowCenter, out ColCenter, out RadiusCircle, out StartPhi, out EndPhi, out _, out ArcAngle);
                if (RowCenter.D > 0)
                {
                    if (DisplayLoction)
                    {
                        HOperatorSet.SetColor(hWindow, CrossColor);
                        Cross.Dispose();
                        HOperatorSet.GenCrossContourXld(out Cross, ResultRow, ResultCol, CrossSize, 0);
                        HOperatorSet.DispObj(Cross, hWindow);
                    }

                    if (DisplayArc)
                    {
                        HOperatorSet.SetLineWidth(hWindow, LineWidth);
                        HOperatorSet.SetColor(hWindow, ArcColor);
                        HOperatorSet.DispObj(Arc, hWindow);
                    }
                    if (DisplayCalib)
                    {
                        HOperatorSet.SetLineWidth(hWindow, 1);
                        HOperatorSet.SetColor(hWindow, CalibColor);
                        HOperatorSet.DispObj(Spoke, hWindow);
                    }
                    HOperatorSet.SetColored(hWindow, 12);
                    HOperatorSet.SetLineWidth(hWindow, 2);
                    HOperatorSet.SetColor(hWindow, "red");
                    FitCircleState = true;
                }
                else
                {
                    HOperatorSet.SetColored(hWindow, 12);
                    HOperatorSet.SetLineWidth(hWindow, 2);
                    HOperatorSet.SetColor(hWindow, "red");
                    MyHOperatorSet.DispMeassge(hWindow, "圆拟合失败", "window", "center", "center", 20, "red");
                    FitCircleState = false;
                }
            }
        }

        public void ReadParameter()
        {
            Elements = Convert.ToInt32(IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "Elements", "0"));
            DetectHeight = Convert.ToInt32(IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "DetectHeight", "0"));
            DetectWidth = Convert.ToInt32(IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "DetectWidth", "0"));
            Sigma = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "Sigma", "0"));
            Threshold = Convert.ToInt32(IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "Threshold", "0"));
            Transition = IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "Transition", "0");
            Select = IniAPI.INIGetStringValue(ArcPath, "ArcParameter", "Select", "0");

            RowCenter = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "FitArcParameter", "RowCenter", "0"));
            ColCenter = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "FitArcParameter", "ColCenter", "0"));
            RadiusCircle = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "FitArcParameter", "RadiusCircle", "0"));
            StartPhi = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "FitArcParameter", "StartPhi", "0"));
            EndPhi = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "FitArcParameter", "EndPhi", "0"));
            ArcAngle = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "FitArcParameter", "ArcAngle", "0"));

            if (Boolean.TryParse(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "DisplayLoction", "0"), out bool a))
            {
                DisplayLoction = Convert.ToBoolean(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "DisplayLoction", "0"));
            }
            else
            {
                DisplayLoction = a;
            }

            if (Boolean.TryParse(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "DisplayCircle", "0"), out bool b))
            {
                DisplayArc = Convert.ToBoolean(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "DisplayCircle", "0"));
            }
            else
            {
                DisplayArc = b;
            }

            if (Boolean.TryParse(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "DisplayCalib", "0"), out bool c))
            {
                DisplayCalib = Convert.ToBoolean(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "DisplayCalib", "0"));
            }
            else
            {
                DisplayCalib = c;
            }

            LineWidth = Convert.ToInt32(IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "LineWidth", "0"));
            ArcColor = IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "CircleColor", "0");
            CrossSize = IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "CrossSize", "0").ToInt32();
            CrossColor = IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "CrossColor", "0");
            CalibColor = IniAPI.INIGetStringValue(ArcPath, "DisplaySet", "CalibColor", "0");

            for (int i = 0; i < Rows.Length; i++)
            {
                Rows[i] = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "DrawArcParameter", "DrawOutRows" + i, "0"));
            }

            for (int i = 0; i < Cols.Length; i++)
            {
                Cols[i] = Convert.ToDouble(IniAPI.INIGetStringValue(ArcPath, "DrawArcParameter", "DrawOutCols" + i, "0"));
            }
        }

        public void WriteParameter()
        {
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "Elements", Elements.ToString());
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "DetectHeight", DetectHeight.ToString());
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "DetectWidth", DetectWidth.ToString());
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "Sigma", Sigma.ToString());
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "Threshold", Threshold.ToString());
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "Transition", Transition.ToString());
            IniAPI.INIWriteValue(ArcPath, "ArcParameter", "Select", Select.ToString());

            IniAPI.INIWriteValue(ArcPath, "FitArcParameter", "RowCenter", RowCenter.ToString());
            IniAPI.INIWriteValue(ArcPath, "FitArcParameter", "ColCenter", ColCenter.ToString());
            IniAPI.INIWriteValue(ArcPath, "FitArcParameter", "RadiusCircle", RadiusCircle.ToString());
            IniAPI.INIWriteValue(ArcPath, "FitArcParameter", "StartPhi", StartPhi.ToString());
            IniAPI.INIWriteValue(ArcPath, "FitArcParameter", "EndPhi", EndPhi.ToString());
            IniAPI.INIWriteValue(ArcPath, "FitArcParameter", "ArcAngle", ArcAngle.ToString());

            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "DisplayLoction", DisplayLoction.ToString());
            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "DisplayCircle", DisplayArc.ToString());
            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "DisplayCalib", DisplayCalib.ToString());


            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "LineWidth", LineWidth.ToString());
            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "CircleColor", ArcColor.ToString());
            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "CrossSize", CrossSize.ToString());
            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "CrossColor", CrossColor.ToString());
            IniAPI.INIWriteValue(ArcPath, "DisplaySet", "CalibColor", CalibColor.ToString());

            for (int i = 0; i < Rows.Length; i++)
            {
                IniAPI.INIWriteValue(ArcPath, "DrawArcParameter", "DrawOutRows" + i, Rows[i].ToString());
            }

            for (int i = 0; i < Cols.Length; i++)
            {
                IniAPI.INIWriteValue(ArcPath, "DrawArcParameter", "DrawOutCols" + i, Cols[i].ToString());
            }
        }

    }
}
